package com.harriague.calculadora.controller;

import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.harriague.calculadora.business.CalculoService;
import com.harriague.calculadora.controller.vo.Input;
import com.harriague.calculadora.controller.vo.Output;
import com.harriague.calculadora.model.Sesion;

import de.congrace.exp4j.UnknownFunctionException;
import de.congrace.exp4j.UnparsableExpressionException;

@Controller
public class CalculoController {

	private static final String ACTION_SAVE = "guardar";
	private static final String ACTION_RECOVER = "recuperar";

	@Autowired
	private CalculoService calculoService;

	@RequestMapping(value = "/{userId}", method = RequestMethod.POST)
	@Transactional
	public @ResponseBody
	Output doCalcular(@RequestBody Input param, @PathVariable String userId) {
		String input = param.getInput();

		Output output = new Output();

		Pattern pat = Pattern.compile("^(" + ACTION_SAVE + "|" + ACTION_RECOVER + ") (.*)");
		java.util.regex.Matcher mat = pat.matcher(input);

		if (mat.matches()) {
			String operation = mat.group(1);
			String value = mat.group(2);

			switch (operation) {
			case ACTION_SAVE:
				try {
					calculoService.save(userId, value);
					output.setOutput(value + " almacenada");
				} catch (IllegalArgumentException e) {
					output.setOutput(e.getMessage());
				}

				break;
			case ACTION_RECOVER:
				Sesion sesion = calculoService.findByUserAndName(userId, value);
				if (sesion != null) {
					output.setOutput(sesion.getCalculos());
				} else {
					output.setOutput("No existe una sesion con ese nombre para ese usuario");
				}
				break;
			}
		} else {
			try {
				output.setOutput(calculoService.calculate(userId, input).toString());
			} catch (UnknownFunctionException e) {
				output.setOutput("No es una funcion reconocida");
			} catch (UnparsableExpressionException e) {
				output.setOutput("No es una expresion correcta");
			}
		}

		return output;

	}

}
